package com.gitee.wsl.data.state.repo

import com.gitee.wsl.data.state.KalugaState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlin.coroutines.CoroutineContext

/**
 * An abstract [BaseHotStateRepo] that uses a [MutableStateFlow] to back up its data.
 * @param State the type of [KalugaState] represented by this repo.
 * @param coroutineContext the [CoroutineContext] used to create a coroutine scope for this state machine. Make sure that if you pass a coroutine context that has sequential execution if you do not want simultaneous state changes. The default Main dispatcher meets these criteria.
 * @param initialState A method for generating the initial [State] the provided repo should be set in when observation starts.
 */
abstract class HotStateFlowRepo<State : KalugaState>(
    coroutineContext: CoroutineContext = Dispatchers.Main.immediate,
    val initialState: (HotStateFlowRepo<State>) -> State
) : BaseHotStateRepo<State, MutableStateFlow<State>>(coroutineContext,),
    StateFlowRepo<State> {

    override val lazyMutableSharedFlow = lazy { MutableStateFlow(initialState(this)) }

    override val stateFlow
        get() = mutableFlow.asStateFlow()

    final override suspend fun initialValue(): State = mutableFlow.value
}